//
//  PhotoSelectorViewController.swift
//  测试-01-照片选择
//
//  Created by teacher on 15/8/7.
//  Copyright © 2015年 itheima. All rights reserved.
//

import UIKit

/// 可重用 cell
private let HMPhotoSelectorViewCell = "HMPhotoSelectorViewCell"
/// 最多允许选择照片数量
private let kPhotoSelectorMaxCount = 9

class PhotoSelectorViewController: UICollectionViewController, PhotoSelectorViewCellDelegate {

    /// 照片数组
    lazy var photos: [UIImage] = [UIImage]()
    /// 当前用户选择的照片索引
    private var currentIndex = 0
    
    // MARK: - 构造函数
    init() {
        super.init(collectionViewLayout: UICollectionViewFlowLayout())
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.backgroundColor = UIColor.whiteColor()
        self.collectionView!.registerClass(PhotoSelectorViewCell.self, forCellWithReuseIdentifier: HMPhotoSelectorViewCell)
        
        // 定义布局的属性
        let layout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout
        // 提示：屏幕越大，展现的内容越多
        layout?.itemSize = CGSize(width: 80, height: 80)
        layout?.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
    }

    // MARK: UICollectionViewDataSource
    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // 保证末尾显示加号按钮，保证能够添加照片
        // 判断如果照片数量达到上限，不再显示 加号按钮
        return (photos.count == kPhotoSelectorMaxCount) ? photos.count : photos.count + 1
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(HMPhotoSelectorViewCell, forIndexPath: indexPath) as! PhotoSelectorViewCell
    
        // Configure the cell
        cell.backgroundColor = UIColor.blueColor()
        // 设置照片
        cell.image = (indexPath.item < photos.count) ? photos[indexPath.item] : nil
        
        // 设置代理
        cell.photoDelegate = self
    
        return cell
    }
    
    // MARK: - PhotoSelectorViewCellDelegate
    // 如果协议是 private，在实现函数的时候，同样也是 private 的
    /// 删除图片
    private func photoSelectorViewCellRemovePhoto(cell: PhotoSelectorViewCell) {
        print(__FUNCTION__)
        
        // 找到用户点击的 cell
        let indexPath = collectionView?.indexPathForCell(cell)
        
        // 删除数组中对应的项
        photos.removeAtIndex(indexPath!.item)
        
        // 刷新数据
        collectionView?.reloadData()
    }

    /// 选择照片
    private func photoSelectorViewCellSelectPhoto(cell: PhotoSelectorViewCell) {
        print(__FUNCTION__)
        
        /**
            PhotoLibrary(默认类型) 照片库－所有的照片，包括使用 iTunes/ iPhoto 同步的照片，不允许删除
            SavedPhotosAlbum    胶卷，就是使用摄像头拍摄的照片，从其他应用程序保存的图片，可以删除
            Camera              相机
        */
        if !UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
            print("无法访问照片库")
            return
        }
        
        // 记录用户选中的 cell 的索引
        let indexPath = collectionView?.indexPathForCell(cell)
        // 记录索引
        currentIndex = indexPath!.item
        print(indexPath)
        
        // 实例化照片选择控制器
        let picker = UIImagePickerController()
        
        // 监听选中的照片
        picker.delegate = self
        // 设置允许编辑 － 会多一个窗口，让用户缩放照片
        // 在实际开发中，如果让用户从照片库选择头像，非常重要！
        // 好处：1. 正方形，2. 图像会小
        // picker.allowsEditing = true
        
        presentViewController(picker, animated: true, completion: nil)
    }
}

// MARK: － UIImagePickerControllerDelegate
extension PhotoSelectorViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    // 注意：一旦实现了代理方法，就需要程序员自己关闭控制器
    func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage, editingInfo: [String : AnyObject]?) {
        
        // 判断用户之前选择的按钮是否有图像
        // `如果有图像，需要更新图像，否则，新增图像`
        // 在实际开发中，只要涉及到相册，都必须要考虑内存！
        // 统一缩放到 300 宽
        let img = image.scaleImage(300)
        
        // 当前的索引和照片的总数相等
        if currentIndex == photos.count {
            // 将图像添加到数组，刷新视图
            photos.append(img)
        } else {
            // 如果小于 总数，说明是之前数组中的某一项
            print("修改 \(currentIndex) 索引项")
            photos[currentIndex] = img
        }
        
        print(img)
        
        collectionView?.reloadData()
        
        // 关闭控制器
        dismissViewControllerAnimated(true, completion: nil)
    }
}

// 提示：如果元素之间有非常明显的包含和被被包含的关系，建议使用代理
private protocol PhotoSelectorViewCellDelegate: NSObjectProtocol {
    /// 选择照片
    func photoSelectorViewCellSelectPhoto(cell: PhotoSelectorViewCell)
    /// 删除照片
    func photoSelectorViewCellRemovePhoto(cell: PhotoSelectorViewCell)
}

/// 照片选择 cell
private class PhotoSelectorViewCell: UICollectionViewCell {
    
    /// cell的图像
    var image: UIImage? {
        didSet {
            
            // 判断图像是否为空
            if image == nil {
                // 显示默认的图像
//                photoButton.setImage(UIImage(named: "compose_pic_add"), forState: UIControlState.Normal)
//                photoButton.setImage(UIImage(named: "compose_pic_add_highlighted"), forState: UIControlState.Highlighted)
                photoButton.setImage("compose_pic_add")
            } else {
                photoButton.setImage(image, forState: UIControlState.Normal)
            }
            
            // 设置删除按钮的隐藏
            removeButton.hidden = (image == nil)
        }
    }
    
    /// 代理
    weak var photoDelegate: PhotoSelectorViewCellDelegate?
    
    // MARK: - 按钮监听方法 － 监听方法是通过运行循环发送消息的，如果类是 private，同样访问不到
    // 两个解决方法
    // 1. 删除类 的 private
    // 2. 如果真的不希望开放这个类给其他对象访问，使用一个关键字 @objc
    // 可以保证即使类是私有的，运行循环同样可以通过消息发送找到该函数
    @objc func clickPhoto() {
        photoDelegate?.photoSelectorViewCellSelectPhoto(self)
    }
    
    @objc func clickRemove() {
        photoDelegate?.photoSelectorViewCellRemovePhoto(self)
    }
    
    // MARK: - 构造函数
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        addSubview(photoButton)
        addSubview(removeButton)
        
        // 自动布局
        photoButton.translatesAutoresizingMaskIntoConstraints = false
        removeButton.translatesAutoresizingMaskIntoConstraints = false
        
        let dict = ["photo": photoButton, "remove": removeButton]
        
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[photo]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict))
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[photo]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict))
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[remove]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict))
        addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[remove]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: dict))
        
        // 添加监听方法
        photoButton.addTarget(self, action: "clickPhoto", forControlEvents: UIControlEvents.TouchUpInside)
        removeButton.addTarget(self, action: "clickRemove", forControlEvents: UIControlEvents.TouchUpInside)
        
        // 修改照片填充模式，按钮的填充模式需要修改 imageView
        // photoButton.contentMode = UIViewContentMode.ScaleAspectFill
        photoButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFill
    }
    
    // MARK: 懒加载
    private lazy var photoButton: UIButton = UIButton(imageName: "compose_pic_add")
    private lazy var removeButton: UIButton = UIButton(imageName: "compose_photo_close")
}
